/**
 * Copyright 厦门中软海晟信息技术有限公司 版权所有 违者必究 2019
 */
package com.opencvjava.lessons.core;

import org.opencv.core.Mat;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

import static com.opencvjava.support.util.CvUtils.clamp;
import static com.opencvjava.support.util.CvUtils.imshow;
import static com.opencvjava.support.util.CvUtils.lutBIB;
import static com.opencvjava.support.util.CvUtils.lutMIM;
import static com.opencvjava.support.util.CvUtils.mat;

/**
 * @author : sunzb(sunzb@hsit.com.cn)
 * @date: 2019/1/4
 */
@Service
public class L7_ContrastAndBrightness {
    public void test() {
        Mat image = mat("lena.jpg");
        if (image.empty()) {
            throw new RuntimeException("图片加载失败");
        }
        imshow("源图", image);
        double alpha = 1.2; /*< Simple contrast control */
        int beta = 0;       /*< Simple brightness control */
        Mat newImage = contrastAndBrightness(image, alpha, beta);
        imshow("New Image1.2", newImage);
        // 更多对比度亮度测试
        more(image);
        // gamma校正
        double gammaValue = 2;
        Map<Integer, Integer> lookUpTable = new HashMap<>();
        for (int i = 0; i < 256; i++) {
            lookUpTable.put(i, (int) (Math.pow(i / 255.0, gammaValue) * 255.0));
        }
        alpha = 1; /*< Simple contrast control */
        beta = 80;       /*< Simple brightness control */
        newImage = contrastAndBrightness(image, alpha, beta);
        imshow("New Image80", newImage);
        newImage = lutMIM(newImage, lookUpTable);
        imshow("伽马校正-亮度", newImage);
        alpha = 1.5; /*< Simple contrast control */
        beta = 0;       /*< Simple brightness control */
        newImage = contrastAndBrightness(image, alpha, beta);
        imshow("New Image1.5", newImage);
        newImage = lutMIM(newImage, lookUpTable);
        imshow("伽马校正-对比度", newImage);
    }

    private void more(Mat image) {
        double alpha;
        int beta;
        Mat newImage;
        alpha = 1.5; /*< Simple contrast control */
        beta = 0;       /*< Simple brightness control */
        newImage = contrastAndBrightness(image, alpha, beta);
        imshow("New Image1.5", newImage);

        alpha = 2; /*< Simple contrast control */
        beta = 0;       /*< Simple brightness control */
        newImage = contrastAndBrightness(image, alpha, beta);
        imshow("New Image2", newImage);

        alpha = 1; /*< Simple contrast control */
        beta = 30;       /*< Simple brightness control */
        newImage = contrastAndBrightness(image, alpha, beta);
        imshow("New Image30", newImage);

        alpha = 1; /*< Simple contrast control */
        beta = 50;       /*< Simple brightness control */
        newImage = contrastAndBrightness(image, alpha, beta);
        imshow("New Image50", newImage);

        alpha = 1; /*< Simple contrast control */
        beta = 80;       /*< Simple brightness control */
        newImage = contrastAndBrightness(image, alpha, beta);
        imshow("New Image80", newImage);
    }

    private Mat contrastAndBrightness(Mat image, double alpha, int beta) {
        Mat dst = new Mat(image.size(), image.type());
        int rows = image.rows();
        int cols = image.cols();
        int channels = image.channels();
        byte[] imageData = new byte[rows * cols * channels];
        image.get(0, 0, imageData);
        byte[] newImageData = new byte[imageData.length];
        int index, color;
        for (int row = 0; row < image.rows(); row++) {
            for (int col = 0; col < image.cols(); col++) {
                for (int channel = 0; channel < image.channels(); channel++) {
                    index = row * cols * channels + col * channels + channel;
                    color = imageData[index] & 0xff;
                    color = color < 0 ? color + 256 : color;
                    newImageData[index] = (byte) (clamp(alpha * color + beta) & 0xff);
                }
            }
        }
        dst.put(0, 0, newImageData);
        return dst;
    }
}
